home *** CD-ROM | disk | FTP | other *** search
/ Stone Design / Stone Design.iso / Stone_Friends / Wave / WavesWorld / Source / IBPalettes / WWTCLKit / WWTextFieldCell.m < prev    next >
Encoding:
Text File  |  1995-03-22  |  21.7 KB  |  696 lines

  1.  
  2. #import "WWTextField.h"
  3. #import "WWTextFieldCell.h"
  4. #import "WWTCLInterp.h"
  5.  
  6. #import "avoidStupidWarnings.h"
  7.  
  8. @implementation WWTextFieldCell
  9.  
  10.  
  11. + initialize { [WWTextFieldCell setVersion:3]; return self; }
  12. ////////////////////////////////////////////////////////
  13. //
  14. - init
  15. {
  16.   [super init];
  17.   controlStringSize = 32;
  18.   controlString = (char *)NXZoneCalloc([self zone], controlStringSize, sizeof(char));
  19.   sprintfControlString = (char *)NXZoneCalloc([self zone], controlStringSize, sizeof(char));
  20.   tclExpressionSize = 32;
  21.   tclExpression = (char *)NXZoneCalloc([self zone], tclExpressionSize, sizeof(char));
  22.   tclVarSize = 32;
  23.   tclVar = (char *)NXZoneCalloc([self zone], tclVarSize, sizeof(char));
  24.   tclCommandSize = 32;
  25.   tclCommand = (char *)NXZoneCalloc([self zone], tclCommandSize, sizeof(char));
  26.   interp = nil;
  27.   tclCommandDirty = YES;
  28.  
  29.   return self;
  30. }
  31. //
  32. - awake
  33. {
  34.   [super awake];
  35.   tclCommandDirty = YES;
  36.   return self;
  37. }
  38.  
  39. - free
  40. {
  41.   if (controlString) { NXZoneFree([self zone], controlString); }
  42.   if (sprintfControlString) { NXZoneFree([self zone], sprintfControlString); }
  43.   if (tclExpression) { NXZoneFree([self zone], tclExpression); }
  44.   if (tclVar) { NXZoneFree([self zone], tclVar); }
  45.   if (tclCommand) { NXZoneFree([self zone], tclCommand); }
  46.   return [super free];
  47. }
  48.  
  49. - reinitializeControlStringAndTclVarFromZone:(NXZone *)zone
  50. {
  51.   controlString = (char *)NXZoneCalloc(zone, controlStringSize, sizeof(char));
  52.   sprintfControlString = (char *)NXZoneCalloc(zone, controlStringSize, sizeof(char));
  53.   tclExpression = (char *)NXZoneCalloc(zone, tclExpressionSize, sizeof(char));
  54.   tclVar = (char *)NXZoneCalloc(zone, tclVarSize, sizeof(char));
  55.   tclCommand = (char *)NXZoneCalloc(zone, tclCommandSize, sizeof(char));
  56.   return self;
  57. }
  58.  
  59. - copyFromZone:(NXZone *)zone
  60. {
  61.   id newCopy = [super copyFromZone:zone];
  62.  
  63.  
  64.   [newCopy reinitializeControlStringAndTclVarFromZone:zone];
  65.   [newCopy setControlString:controlString];
  66.   [newCopy setTclExpression:tclExpression];
  67.   [newCopy setTclVar:tclVar];
  68.   [newCopy setTclCommand:tclCommand];
  69.  
  70.   return newCopy;
  71. }
  72.  
  73. - setStringValue:(const char *)str
  74. {
  75.   [super setStringValue:str];
  76.   tclCommandDirty = YES;
  77.   return self;
  78. }
  79.  
  80. - setIntValue:(int)val
  81. {
  82.   [super setIntValue:val];
  83.   tclCommandDirty = YES;
  84.   return self;
  85. }
  86.  
  87. - setFloatValue:(float)val
  88. {
  89.   [super setFloatValue:val];
  90.   tclCommandDirty = YES;
  91.   return self;
  92. }
  93.  
  94. - setDoubleValue:(double)val
  95. {
  96.   [super setDoubleValue:val];
  97.   tclCommandDirty = YES;
  98.   return self;
  99. }
  100.  
  101. - setInterp:newInterp { interp = newInterp; return self; }
  102. - interp { return interp; }
  103.  
  104. - resizeTclCommandForArgVector:(char *)argOrderVector
  105. {
  106.   BOOL    done = NO;
  107.  
  108.  
  109.   // this case handles all single numbers.  We figure the max printable length of a number is 32
  110.   if (!done && (!strcmp("d", argOrderVector) || !strcmp("f", argOrderVector) || !strcmp("S", argOrderVector)))
  111.   {  while (tclCommandSize < (controlStringSize + 32))
  112.      {  if (!tclCommandSize)
  113.     {  tclCommandSize = 32;
  114.            tclCommand = (char *)NXZoneCalloc([self zone], tclCommandSize, sizeof(char));
  115.         }
  116.         else
  117.         {  tclCommandSize *= 2;
  118.            tclCommand = (char *)NXZoneRealloc([self zone], tclCommand, tclCommandSize);
  119.         }
  120.      }
  121.      done = YES;
  122.   }
  123.  
  124.   // this case handles three numbers
  125.   if (!done && (!strcmp("fff", argOrderVector) || !strcmp("RGB", argOrderVector)))
  126.   {  while (tclCommandSize  < (controlStringSize + (2 + (3 * 32))))
  127.      {  if (!tclCommandSize)
  128.     {  tclCommandSize = 32;
  129.            tclCommand = (char *)NXZoneCalloc([self zone], tclCommandSize, sizeof(char));
  130.         }
  131.         else
  132.         {  tclCommandSize *= 2;
  133.            tclCommand = (char *)NXZoneRealloc([self zone], tclCommand, tclCommandSize);
  134.         }
  135.      }
  136.      done = YES;
  137.   }
  138.  
  139.   // these two cases handle single strings
  140.   if (!done && (!strcmp("s", argOrderVector)))
  141.   {  const char  *str = [self stringValue]; 
  142.      int   strLen = 1 + strlen(str);
  143.  
  144.      while (tclCommandSize < (controlStringSize + strLen))
  145.      {  if (!tclCommandSize)
  146.     {  tclCommandSize = 32;
  147.            tclCommand = (char *)NXZoneCalloc([self zone], tclCommandSize, sizeof(char));
  148.         }
  149.         else
  150.         {  tclCommandSize *= 2;
  151.            tclCommand = (char *)NXZoneRealloc([self zone], tclCommand, tclCommandSize);
  152.         }
  153.      }
  154.      done = YES;
  155.   }
  156.  
  157.   if (!done && (!strcmp("F", argOrderVector)))
  158.   {  const char  *str = [[self font] name]; 
  159.      int   strLen = 1 + strlen(str);
  160.  
  161.      while (tclCommandSize < (controlStringSize + strLen))
  162.      {  if (!tclCommandSize)
  163.     {  tclCommandSize = 32;
  164.            tclCommand = (char *)NXZoneCalloc([self zone], tclCommandSize, sizeof(char));
  165.         }
  166.         else
  167.         {  tclCommandSize *= 2;
  168.            tclCommand = (char *)NXZoneRealloc([self zone], tclCommand, tclCommandSize);
  169.         }
  170.      }
  171.      done = YES;
  172.   }
  173.  
  174.   // those were the easy ones; now for the permutations...
  175.  
  176.   // two strings
  177.   if (!done && (!strcmp("Fs", argOrderVector) || !strcmp("sF", argOrderVector)))
  178.   {  const char  *str1 = [[self font] name]; 
  179.      const char  *str2 = [self stringValue];
  180.      int   strLen = 2 + strlen(str1) + strlen(str2);
  181.  
  182.      while (tclCommandSize < (controlStringSize + strLen))
  183.      {  if (!tclCommandSize)
  184.     {  tclCommandSize = 32;
  185.            tclCommand = (char *)NXZoneCalloc([self zone], tclCommandSize, sizeof(char));
  186.         }
  187.         else
  188.         {  tclCommandSize *= 2;
  189.            tclCommand = (char *)NXZoneRealloc([self zone], tclCommand, tclCommandSize);
  190.         }
  191.      }
  192.      done = YES;
  193.   }
  194.  
  195.   // a string and a number
  196.   if (!done && (   !strcmp("sf", argOrderVector) || !strcmp("fs", argOrderVector)
  197.                 || !strcmp("sd", argOrderVector) || !strcmp("ds", argOrderVector)
  198.                 || !strcmp("sS", argOrderVector) || !strcmp("Ss", argOrderVector)))
  199.   {  const char  *str = [self stringValue];
  200.      int   strLen = 1 + strlen(str);
  201.  
  202.  
  203.      while (tclCommandSize < (controlStringSize + strLen + 32))
  204.      {  if (!tclCommandSize)
  205.     {  tclCommandSize = 32;
  206.            tclCommand = (char *)NXZoneCalloc([self zone], tclCommandSize, sizeof(char));
  207.         }
  208.         else
  209.         {  tclCommandSize *= 2;
  210.            tclCommand = (char *)NXZoneRealloc([self zone], tclCommand, tclCommandSize);
  211.         }
  212.      }
  213.      done = YES;
  214.   }
  215.  
  216.   if (!done && (   !strcmp("fF", argOrderVector) || !strcmp("Ff", argOrderVector) 
  217.                 || !strcmp("dF", argOrderVector) || !strcmp("Fd", argOrderVector)
  218.                 || !strcmp("SF", argOrderVector) || !strcmp("FS", argOrderVector)))
  219.   {  const char  *str = [[self font] name]; 
  220.      int   strLen = 1 + strlen(str);
  221.  
  222.      while (tclCommandSize < (controlStringSize + strLen + 32))
  223.      {  if (!tclCommandSize)
  224.     {  tclCommandSize = 32;
  225.            tclCommand = (char *)NXZoneCalloc([self zone], tclCommandSize, sizeof(char));
  226.         }
  227.         else
  228.         {  tclCommandSize *= 2;
  229.            tclCommand = (char *)NXZoneRealloc([self zone], tclCommand, tclCommandSize);
  230.         }
  231.      }
  232.      done = YES;
  233.   }
  234.  
  235.   // two strings, one number
  236.   if (!done && (   !strcmp("Fsd", argOrderVector) || !strcmp("sFd", argOrderVector)
  237.                 || !strcmp("Fsf", argOrderVector) || !strcmp("sFf", argOrderVector)
  238.                 || !strcmp("FsS", argOrderVector) || !strcmp("sFS", argOrderVector)
  239.                 || !strcmp("dFs", argOrderVector) || !strcmp("dsF", argOrderVector)
  240.                 || !strcmp("fFs", argOrderVector) || !strcmp("fsF", argOrderVector)
  241.                 || !strcmp("SFs", argOrderVector) || !strcmp("SsF", argOrderVector)
  242.                 || !strcmp("Fds", argOrderVector) || !strcmp("sdF", argOrderVector)
  243.                 || !strcmp("Ffs", argOrderVector) || !strcmp("sfF", argOrderVector)
  244.                 || !strcmp("FSs", argOrderVector) || !strcmp("sSF", argOrderVector)))
  245.   {  const char  *str1 = [[self font] name]; 
  246.      const char  *str2 = [self stringValue];
  247.      int   strLen = 2 + strlen(str1) + strlen(str2);
  248.  
  249.      while (tclCommandSize < (controlStringSize + strLen + 32))
  250.      {  if (!tclCommandSize)
  251.     {  tclCommandSize = 32;
  252.            tclCommand = (char *)NXZoneCalloc([self zone], tclCommandSize, sizeof(char));
  253.         }
  254.         else
  255.         {  tclCommandSize *= 2;
  256.            tclCommand = (char *)NXZoneRealloc([self zone], tclCommand, tclCommandSize);
  257.         }
  258.      }
  259.      done = YES;
  260.   }
  261.  
  262.   return self;
  263. }
  264.  
  265.  
  266. - updateTclCommand
  267. {
  268.   char     *controlStringPtr, *sprintfControlStringPtr;
  269.   BOOL     done;
  270.   int      argOrderSize = 32;
  271.   char     *argOrderVector = (char *)NXZoneCalloc([self zone], argOrderSize, sizeof(char));
  272.   int      argOrderOffset = 0;
  273.   NXColor  color = [self textColor];
  274.  
  275.  
  276.   if (!controlString)
  277.   {  return nil;
  278.   }
  279.  
  280.   // we want to grovel over the controlString, 
  281.   // for right now, we really only tend to have the following patterns 
  282.   // in the controlString: 1 %f, 1 %d, 1 %s, %R, %G, %B
  283.   // some new ones for doing string stuff: %F %S %s, and %F %s
  284.   controlStringPtr = controlString;
  285.   sprintfControlStringPtr = sprintfControlString;
  286.   strcpy(sprintfControlString, controlString);
  287.   while (*controlStringPtr)
  288.   {  if (*controlStringPtr == '%')
  289.      {  sprintfControlStringPtr++;  controlStringPtr++;
  290.         if (*controlStringPtr)
  291.         {  switch (*controlStringPtr)
  292.            {  case 'd':    while (argOrderOffset >= argOrderSize)
  293.                         {  argOrderSize *= 2;
  294.                            argOrderVector = (char *)NXZoneRealloc([self zone], argOrderVector, argOrderSize);
  295.                         }
  296.                         argOrderVector[argOrderOffset++] = 'd';
  297.                         sprintfControlStringPtr++; controlStringPtr++;
  298.             break;
  299.               case 'f':    while (argOrderOffset >= argOrderSize)
  300.                         {  argOrderSize *= 2;
  301.                            argOrderVector = (char *)NXZoneRealloc([self zone], argOrderVector, argOrderSize);
  302.                         }
  303.                         argOrderVector[argOrderOffset++] = 'f';
  304.                         sprintfControlStringPtr++; controlStringPtr++;
  305.             break;
  306.               case 'S':    while (argOrderOffset >= argOrderSize)
  307.                         {  argOrderSize *= 2;
  308.                            argOrderVector = (char *)NXZoneRealloc([self zone], argOrderVector, argOrderSize);
  309.                         }
  310.                         argOrderVector[argOrderOffset++] = 'S'; *sprintfControlStringPtr++ = 'f';
  311.                         sprintfControlStringPtr++; controlStringPtr++;
  312.             break;
  313.               case 's':    while (argOrderOffset >= argOrderSize)
  314.                         {  argOrderSize *= 2;
  315.                            argOrderVector = (char *)NXZoneRealloc([self zone], argOrderVector, argOrderSize);
  316.                         }
  317.                         argOrderVector[argOrderOffset++] = 's';
  318.                         sprintfControlStringPtr++; controlStringPtr++;
  319.             break;
  320.               case 'F':    while (argOrderOffset >= argOrderSize)
  321.                         {  argOrderSize *= 2;
  322.                            argOrderVector = (char *)NXZoneRealloc([self zone], argOrderVector, argOrderSize);
  323.                         }
  324.                         argOrderVector[argOrderOffset++] = 'F'; *sprintfControlStringPtr++ = 's';
  325.                         controlStringPtr++;
  326.             break;
  327.               case 'R':    while (argOrderOffset >= argOrderSize)
  328.                         {  argOrderSize *= 2;
  329.                            argOrderVector = (char *)NXZoneRealloc([self zone], argOrderVector, argOrderSize);
  330.                         }
  331.                         argOrderVector[argOrderOffset++] = 'R';
  332.                         *sprintfControlStringPtr++ = 'f'; controlStringPtr++;
  333.                         break;
  334.               case 'G':    while (argOrderOffset >= argOrderSize)
  335.                         {  argOrderSize *= 2;
  336.                            argOrderVector = (char *)NXZoneRealloc([self zone], argOrderVector, argOrderSize);
  337.                         }
  338.                         argOrderVector[argOrderOffset++] = 'G';
  339.                         *sprintfControlStringPtr++ = 'f'; controlStringPtr++;
  340.                         break;
  341.               case 'B':    while (argOrderOffset >= argOrderSize)
  342.                         {  argOrderSize *= 2;
  343.                            argOrderVector = (char *)NXZoneRealloc([self zone], argOrderVector, argOrderSize);
  344.                         }
  345.                         argOrderVector[argOrderOffset++] = 'B'; *sprintfControlStringPtr++ = 'f';
  346.                         controlStringPtr++;
  347.                         break;
  348.               case '%':    sprintfControlStringPtr++; controlStringPtr++;
  349.                         break;
  350.                default:    NXLogError("WWSliderCell: unknown specifier <%c> in controlString.\n", *controlStringPtr);
  351.                         sprintfControlStringPtr++; controlStringPtr++;
  352.             break;
  353.            }
  354.        }
  355.      }
  356.      else
  357.      {  sprintfControlStringPtr++;  controlStringPtr++;
  358.      }
  359.   }
  360.   argOrderVector[argOrderOffset] = 0;
  361.  
  362.   done = NO;
  363.  
  364.   // since strings are really the only variable length thing that
  365.   // could get shoved into the tclCommand, we really should have a flag in
  366.   // the above switch in case we don't encounter any tags that correspond
  367.   // to strings.  If we don't, it's wicked easy to grow the tclCommand
  368.   // buffer...
  369.  
  370.   if (!done && !strcmp("d", argOrderVector))
  371.   {  [self resizeTclCommandForArgVector:argOrderVector];
  372.      sprintf(tclCommand, sprintfControlString, [self intValue]);
  373.      done = YES;
  374.   }
  375.   if (!done && !strcmp("f", argOrderVector))
  376.   {  [self resizeTclCommandForArgVector:argOrderVector];
  377.      sprintf(tclCommand, sprintfControlString, [self floatValue]);
  378.      done = YES;
  379.   }
  380.   if (!done && !strcmp("s", argOrderVector))
  381.   {  [self resizeTclCommandForArgVector:argOrderVector];
  382.      sprintf(tclCommand, sprintfControlString, [self stringValue]);
  383.      done = YES;
  384.   }
  385.  
  386.   if (!done && !strcmp("FSs", argOrderVector))
  387.   {  [self resizeTclCommandForArgVector:argOrderVector];
  388.      sprintf(tclCommand, sprintfControlString, [[self font] name], [[self font] pointSize], [self stringValue]);
  389.      done = YES;
  390.   }
  391.  
  392.   if (!done && !strcmp("Fs", argOrderVector))
  393.   {  [self resizeTclCommandForArgVector:argOrderVector];
  394.      sprintf(tclCommand, sprintfControlString, [[self font] name], [self stringValue]);
  395.      done = YES;
  396.   }
  397.  
  398.   // for back compatibility
  399.   if (!done && !strcmp("fff", argOrderVector))
  400.   {  [self resizeTclCommandForArgVector:argOrderVector];
  401.      sprintf(tclCommand, sprintfControlString, NXRedComponent(color), NXGreenComponent(color), NXBlueComponent(color));
  402.      done = YES;
  403.   }
  404.   if (!done && !strcmp("RGB", argOrderVector))
  405.   {  [self resizeTclCommandForArgVector:argOrderVector];
  406.      sprintf(tclCommand, sprintfControlString, NXRedComponent(color), NXGreenComponent(color), NXBlueComponent(color));
  407.      done = YES;
  408.   }
  409.   if (!done && !strcmp("fRGB", argOrderVector))
  410.   {  [self resizeTclCommandForArgVector:argOrderVector];
  411.      sprintf(tclCommand, sprintfControlString, [self floatValue], NXRedComponent(color), NXGreenComponent(color), NXBlueComponent(color));
  412.      done = YES;
  413.   }
  414.   if (!done && !strcmp("RGBf", argOrderVector))
  415.   {  [self resizeTclCommandForArgVector:argOrderVector];
  416.      sprintf(tclCommand, sprintfControlString, NXRedComponent(color), NXGreenComponent(color), NXBlueComponent(color), [self floatValue]);
  417.      done = YES;
  418.   }
  419.   if (!done && !strcmp("dRGB", argOrderVector))
  420.   {  [self resizeTclCommandForArgVector:argOrderVector];
  421.      sprintf(tclCommand, sprintfControlString, [self intValue], NXRedComponent(color), NXGreenComponent(color), NXBlueComponent(color));
  422.      done = YES;
  423.   }
  424.   if (!done && !strcmp("RGBd", argOrderVector))
  425.   {  [self resizeTclCommandForArgVector:argOrderVector];
  426.      sprintf(tclCommand, sprintfControlString, NXRedComponent(color), NXGreenComponent(color), NXBlueComponent(color), [self intValue]);
  427.      done = YES;
  428.   }
  429.  
  430.   if (!done)
  431.   {  while (tclCommandSize < controlStringSize)
  432.      {  if (!tclCommandSize)
  433.     {  tclCommandSize = 32;
  434.            tclCommand = (char *)NXZoneCalloc([self zone], tclCommandSize, sizeof(char));
  435.         }
  436.         else
  437.         {  tclCommandSize *= 2;
  438.            tclCommand = (char *)NXZoneRealloc([self zone], tclCommand, tclCommandSize);
  439.         }
  440.      }
  441.      strcpy(tclCommand, controlString);
  442.   }
  443.   tclCommandDirty = NO;
  444.  
  445.   NXZoneFree([self zone], argOrderVector);
  446.  
  447.   return self;
  448. }
  449.  
  450.  
  451. - evaluateSelf
  452. {
  453.    int   ret;
  454.    char  *newStringValue;
  455.    id    retID;
  456.  
  457.  
  458.   newStringValue = [interp globalEval:tclExpression :&ret];
  459.   if ((ret == TCL_OK) || (ret == TCL_RETURN))
  460.   {  [self setStringValue:newStringValue];
  461.      retID = self;
  462.   }
  463.   else
  464.   {  NXLogError("WWSliderCell: error <%s> evaluating tcl expression <%s>\n", 
  465.         newStringValue, tclExpression);
  466.      if (newStringValue) { free(newStringValue); }
  467.      retID = nil;
  468.   }
  469.   return retID;
  470. }
  471.  
  472. - updateInterp
  473. {
  474.   if ([interp eval:[self tclCommand]])
  475.   {  return self;
  476.   }
  477.   return nil;
  478. }
  479.  
  480.  
  481. - setControlString:(const char *)str 
  482.   int   cnt;
  483.  
  484.  
  485.   if (!str) { return self; }
  486.   if (controlStringSize <= 0) 
  487.   {  controlStringSize = 32; 
  488.      controlString = (char *)NXZoneCalloc([self zone], controlStringSize, sizeof(char));
  489.   }
  490.   cnt = strlen(str);
  491.   while (cnt >= controlStringSize)
  492.   {  controlStringSize *= 2;
  493.      controlString = (char *)NXZoneRealloc([self zone], controlString, controlStringSize);
  494.   }
  495.   if (sprintfControlString)
  496.   {  sprintfControlString = (char *)NXZoneRealloc([self zone], sprintfControlString, controlStringSize);
  497.   }
  498.   else
  499.   {  sprintfControlString = (char *)NXZoneCalloc([self zone], controlStringSize, sizeof(char));
  500.   }
  501.   strcpy(controlString, str); 
  502.   tclCommandDirty = YES;
  503.   return self; 
  504. }
  505. //
  506. - (const char *)controlString { return controlString; }
  507.  
  508. - setTclExpression:(const char *)str 
  509.   int   cnt;
  510.  
  511.  
  512.   if (!str) { return self; }
  513.   if (tclExpressionSize <= 0) 
  514.   {  tclExpressionSize = 32; 
  515.      tclExpression = (char *)NXZoneCalloc([self zone], tclExpressionSize, sizeof(char));
  516.   }
  517.   cnt = strlen(str);
  518.   while (cnt >= tclExpressionSize)
  519.   {  tclExpressionSize *= 2;
  520.      tclExpression = (char *)NXZoneRealloc([self zone], tclExpression, tclExpressionSize);
  521.   }
  522.   strcpy(tclExpression, str); 
  523.   return self; 
  524. }
  525. //
  526. - (const char *)tclExpression { return tclExpression; }
  527.  
  528. - setTclVar:(const char *)str 
  529.   int   cnt;
  530.  
  531.  
  532.   if (!str) { return self; }
  533.   if (tclVarSize <= 0) 
  534.   {  tclVarSize = 32; 
  535.      tclVar = (char *)NXZoneCalloc([self zone], tclVarSize, sizeof(char));
  536.   }
  537.   cnt = strlen(str);
  538.   while (cnt >= tclVarSize)
  539.   {  tclVarSize *= 2;
  540.      tclVar = (char *)NXZoneRealloc([self zone], tclVar, tclVarSize);
  541.   }
  542.   strcpy(tclVar, str); 
  543.   return self; 
  544. }
  545. //
  546. - (const char *)tclVar { return tclVar; }
  547.  
  548. - setTclCommand:(const char *)str 
  549.   int   cnt;
  550.  
  551.  
  552.   if (!str) { return self; }
  553.   if (tclCommandSize <= 0) 
  554.   {  tclCommandSize = 32; 
  555.      tclCommand = (char *)NXZoneCalloc([self zone], tclCommandSize, sizeof(char));
  556.   }
  557.   cnt = strlen(str);
  558.   while (cnt >= tclCommandSize)
  559.   {  tclCommandSize *= 2;
  560.      tclCommand = (char *)NXZoneRealloc([self zone], tclCommand, tclCommandSize);
  561.   }
  562.   strcpy(tclCommand, str); 
  563.   return self; 
  564. }
  565. //
  566. - (const char *)tclCommand 
  567.   if (tclCommandDirty)
  568.   {  [self updateTclCommand];
  569.   }
  570.   return tclCommand; 
  571. }
  572.  
  573. - write:(NXTypedStream *)stream 
  574. {
  575.    [super write:stream];
  576.    NXWriteType(stream, "*", &controlString);
  577.    NXWriteType(stream, "*", &tclVar);
  578.    NXWriteType(stream, "*", &tclExpression);
  579.    NXWriteType(stream, "*", &tclCommand);
  580.    NXWriteObjectReference(stream, interp);
  581.    return self;
  582. }
  583. //
  584. - read:(NXTypedStream *)stream 
  585. {
  586.    int version;
  587.  
  588.    [super read:stream];
  589.  
  590.    version = NXTypedStreamClassVersion(stream, "WWTextFieldCell");
  591.    if (version == 1)
  592.    {  NXReadType(stream, "*", &controlString);
  593.       if (controlString) 
  594.       {  controlStringSize = strlen(controlString) + 1;
  595.          sprintfControlString = (char *)NXZoneCalloc([self zone], controlStringSize, sizeof(char));
  596.       }
  597.       else
  598.       {  controlStringSize = 0;
  599.          sprintfControlString = NULL;
  600.       }
  601.       NXReadType(stream, "*", &tclVar);
  602.       if (tclVar) 
  603.       {  tclVarSize = strlen(tclVar) + 1;
  604.       }
  605.       else
  606.       { tclVarSize = 0;
  607.       }
  608.       tclExpressionSize = 32;
  609.       tclExpression = (char *)NXZoneCalloc([self zone], tclExpressionSize, sizeof(char));
  610.       interp = nil;
  611.       tclCommandSize = 0;
  612.       tclCommand = NULL;
  613.    }
  614.    if (version == 2)
  615.    {  NXReadType(stream, "*", &controlString);
  616.       if (controlString) 
  617.       {  controlStringSize = strlen(controlString) + 1;
  618.          sprintfControlString = (char *)NXZoneCalloc([self zone], controlStringSize, sizeof(char));
  619.       }
  620.       else
  621.       {  controlStringSize = 0;
  622.          sprintfControlString = NULL;
  623.       }
  624.       NXReadType(stream, "*", &tclVar);
  625.       if (tclVar) 
  626.       {  tclVarSize = strlen(tclVar) + 1;
  627.       }
  628.       else
  629.       { tclVarSize = 0;
  630.       }
  631.       NXReadType(stream, "*", &tclExpression);
  632.       if (tclExpression) 
  633.       {  tclExpressionSize = strlen(tclExpression) + 1;
  634.       }
  635.       else
  636.       {  tclExpressionSize = 0;
  637.       }
  638.       interp = nil;
  639.       tclCommandSize = 0;
  640.       tclCommand = NULL;
  641.    }
  642.    if (version == 3)
  643.    {  NXReadType(stream, "*", &controlString);
  644.       if (controlString) 
  645.       {  controlStringSize = strlen(controlString) + 1;
  646.          sprintfControlString = (char *)NXZoneCalloc([self zone], controlStringSize, sizeof(char));
  647.       }
  648.       else
  649.       {  controlStringSize = 0;
  650.          sprintfControlString = NULL;
  651.       }
  652.       NXReadType(stream, "*", &tclVar);
  653.       if (tclVar) 
  654.       {  tclVarSize = strlen(tclVar) + 1;
  655.       }
  656.       else
  657.       { tclVarSize = 0;
  658.       }
  659.       NXReadType(stream, "*", &tclExpression);
  660.       if (tclExpression) 
  661.       {  tclExpressionSize = strlen(tclExpression) + 1;
  662.       }
  663.       else
  664.       {  tclExpressionSize = 0;
  665.       }
  666.       NXReadType(stream, "*", &tclCommand);
  667.       if (tclCommand) 
  668.       {  tclCommandSize = strlen(tclCommand) + 1;
  669.       }
  670.       else
  671.       {  tclCommandSize = 0;
  672.       }
  673.       interp = NXReadObject(stream);
  674.    }
  675.    return self;
  676. }
  677.  
  678. // IB stuff
  679. - (const char *)getInspectorClassName 
  680. {  
  681.    NXEvent  *event = [NXApp currentEvent];
  682.  
  683.    if (event->flags & NX_ALTERNATEMASK)
  684.    {  return [super getInspectorClassName];
  685.    }
  686.    
  687.    return "WWTextFieldCellIBInspector"; 
  688. }
  689.  
  690. @end
  691.